# Spring Security - Authentication and Authorization
API์ ๊ถํ ๊ธฐ๋ฅ์ด ์์ผ๋ฉด, ์๋ฌด๋ ํ์ ์ ๋ณด๋ฅผ ์กฐํํ๊ณ ์์ ํ๊ณ ์ญ์ ํ ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ๋ง๊ธฐ ์ํด ์ธ์ฆ๋ ์ ์ ๋ง API๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํด์ผํ๋๋ฐ, ์ด๋ ์ฌ์ฉํ ์ ์๋ ํด๊ฒฐ ์ฑ
์ค ํ๋๊ฐ Spring Security๋ค.
์คํ๋ง ํ๋ ์์ํฌ์์๋ ์ธ์ฆ ๋ฐ ๊ถํ ๋ถ์ฌ๋ก ๋ฆฌ์์ค ์ฌ์ฉ์ ์ปจํธ๋กค ํ ์ ์๋ Spring Security
๋ฅผ ์ ๊ณตํ๋ค. ์ด ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ฉด, ๋ณด์ ์ฒ๋ฆฌ๋ฅผ ์์ฒด์ ์ผ๋ก ๊ตฌํํ์ง ์์๋ ์ฝ๊ฒ ํ์ํ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.
Spring Security๋ ์คํ๋ง์ DispatcherServlet
์๋จ์ Filter ํํ๋ก ์์นํ๋ค. Dispatcher๋ก ๋์ด๊ฐ๊ธฐ ์ ์ ์ด Filter๊ฐ ์์ฒญ์ ๊ฐ๋ก์ฑ์, ํด๋ผ์ด์ธํธ์ ๋ฆฌ์์ค ์ ๊ทผ ๊ถํ์ ํ์ธํ๊ณ , ์๋ ๊ฒฝ์ฐ์๋ ์ธ์ฆ ์์ฒญ ํ๋ฉด์ผ๋ก ์๋ ๋ฆฌ๋ค์ด๋ ํธํ๋ค.
# Spring Security Filter
Filter์ ์ข
๋ฅ๋ ์๋นํ ๋ง๋ค. ์์์ ์์๋ก ๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ ๊ถํ์ด ์์ ๋ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ ํํฐ๋ UsernamePasswordAuthenticationFilter
๋ค.
์ธ์ฆ ๊ถํ์ด ์์ ๋ ์ค๋ฅ๋ฅผ JSON์ผ๋ก ๋ด๋ ค์ฃผ๊ธฐ ์ํด ํด๋น ํํฐ๊ฐ ์คํ๋๊ธฐ ์ ์ฒ๋ฆฌ๊ฐ ํ์ํ ๊ฒ์ด๋ค.
API ์ธ์ฆ ๋ฐ ๊ถํ ๋ถ์ฌ๋ฅผ ์ํ ์์ ์์๋ ์๋์ ๊ฐ์ด ๊ตฌ์ฑํ ์ ์๋ค.
- ํ์ ๊ฐ์ , ๋ก๊ทธ์ธ API ๊ตฌํ
- ๋ฆฌ์์ค ์ ๊ทผ ๊ฐ๋ฅํ ROLE_USER ๊ถํ์ ๊ฐ์ ํ์์๊ฒ ๋ถ์ฌ
- Spring Security ์ค์ ์์ ROLE_USER ๊ถํ์ ๊ฐ์ง๋ฉด ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ์ธํ
- ๊ถํ์ด ์๋ ํ์์ด ๋ก๊ทธ์ธ ์ฑ๊ณตํ๋ฉด ๋ฆฌ์์ค ์ ๊ทผ ๊ฐ๋ฅํ JWT ํ ํฐ ๋ฐ๊ธ
- ํด๋น ํ์์ ๊ถํ์ด ํ์ํ API ์ ๊ทผ ์ JWT ๋ณด์ ํ ํฐ์ ์ฌ์ฉ
์ด์ฒ๋ผ ์ ๊ทผ ์ ํ์ด ํ์ํ API์๋ ๋ณด์ ํ ํฐ์ ํตํด์ ์ด ์ ์ ๊ฐ ๊ถํ์ด ์๋์ง ์ฌ๋ถ๋ฅผ Spring Security๋ฅผ ํตํด ์ฒดํฌํ๊ณ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ ์ ์๋๋ก ๊ตฌ์ฑํ ์ ์๋ค.
# Spring Security Configuration
์๋ฒ์ ๋ณด์์ ์ค์ ํ๊ธฐ ์ํด Configuration์ ๋ง๋ ๋ค. ๊ธฐ์กด ์์์ฒ๋ผ, USER์ ๋ํ ๊ถํ์ ์ค์ ํ๊ธฐ ์ํ ์์ ๋ ์ฌ๊ธฐ์ ์งํ๋๋ค.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable() // rest api ์ด๋ฏ๋ก ๊ธฐ๋ณธ์ค์ ์ฌ์ฉ์ํจ. ๊ธฐ๋ณธ์ค์ ์ ๋น์ธ์ฆ์ ๋ก๊ทธ์ธํผ ํ๋ฉด์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ
.cors().configurationSource(corsConfigurationSource())
.and()
.csrf().disable() // rest api์ด๋ฏ๋ก csrf ๋ณด์์ด ํ์์์ผ๋ฏ๋ก disable์ฒ๋ฆฌ.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // jwt token์ผ๋ก ์ธ์ฆํ๋ฏ๋ก ์ธ์
์ ํ์์์ผ๋ฏ๋ก ์์ฑ์ํจ.
.and()
.authorizeRequests() // ๋ค์ ๋ฆฌํ์คํธ์ ๋ํ ์ฌ์ฉ๊ถํ ์ฒดํฌ
.antMatchers("/*/signin", "/*/signin/**", "/*/signup", "/*/signup/**", "/social/**").permitAll() // ๊ฐ์
๋ฐ ์ธ์ฆ ์ฃผ์๋ ๋๊ตฌ๋ ์ ๊ทผ๊ฐ๋ฅ
.antMatchers(HttpMethod.GET, "home/**").permitAll() // home์ผ๋ก ์์ํ๋ GET์์ฒญ ๋ฆฌ์์ค๋ ๋๊ตฌ๋ ์ ๊ทผ๊ฐ๋ฅ
.anyRequest().hasRole("USER") // ๊ทธ์ธ ๋๋จธ์ง ์์ฒญ์ ๋ชจ๋ ์ธ์ฆ๋ ํ์๋ง ์ ๊ทผ ๊ฐ๋ฅ
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class); // jwt token ํํฐ๋ฅผ id/password ์ธ์ฆ ํํฐ ์ ์ ๋ฃ๋๋ค
}